﻿using System;
using System.Collections.Generic;
using Verse;
using UnityEngine;
using RimWorld;
using System.Linq;
using Verse.AI.Group;

namespace SZ.Mech
{
    /// <summary>
    /// 机械机甲集群
    /// </summary>
    public class IncidentWorker_HeavenForgedMechCluster: IncidentWorker
    {

        protected override bool CanFireNowSub(IncidentParms parms)
        {
            return SZ_DefOf.SZ_HeavenForgedCelestiall != null;
        }

        protected override bool TryExecuteWorker(IncidentParms parms)
        {
            Map map = (Map)parms.target;
            List<TargetInfo> list = new List<TargetInfo>();

            //supressor
            ThingDef shipPartDef = def.mechClusterBuilding;
            IntVec3 intVec = FindDropPodLocation(map, (IntVec3 spot) => CanPlaceAt(spot));
            bool CanPlaceAt(IntVec3 loc)
            {
                CellRect cellRect = GenAdj.OccupiedRect(loc, Rot4.North, shipPartDef.Size);
                if (loc.Fogged(map) || !cellRect.InBounds(map))
                {
                    return false;
                }

                if (!DropCellFinder.SkyfallerCanLandAt(loc, map, shipPartDef.Size))
                {
                    return false;
                }

                foreach (IntVec3 item2 in cellRect)
                {
                    RoofDef roof = item2.GetRoof(map);
                    if (roof != null && roof.isNatural)
                    {
                        return false;
                    }
                }

                return GenConstruct.CanBuildOnTerrain(shipPartDef, loc, map, Rot4.North);
            }

            if (intVec == IntVec3.Invalid)
            {
                return false;
            }

            //天兵集群派系
            Faction FactionHeavenForged = Find.FactionManager.FirstFactionOfDef(SZ_DefOf.SZ_HeavenForgedCelestiall);
            float points = Mathf.Max(parms.points * 1.1f, 300f);

            List<Pawn> listPawn = PawnGroupMakerUtility.GeneratePawns(new PawnGroupMakerParms
            {
                groupKind = PawnGroupKindDefOf.Combat,
                tile = map.Tile,
                faction = FactionHeavenForged,
                points = points
            }).ToList();

            Thing thing = ThingMaker.MakeThing(shipPartDef);
            thing.SetFaction(FactionHeavenForged);

            LordMaker.MakeNewLord(FactionHeavenForged, new LordJob_AssaultColony(), map, listPawn);

            List<Thing> listSculpture = new List<Thing>();

            
             
            ///生成天兵单位，然后被装进去
            foreach (Pawn item in listPawn)
            {
                Thing sculpture = ThingMaker.MakeThing(SZ_DefOf.SZ_MechSculpture);
                sculpture.TryGetComp<CompHitToActive>()?.SetCachedPawn(item);
                sculpture.SetFaction(FactionHeavenForged);
                listSculpture.Add(sculpture);
            }

            //turret
            MechClusterProps props = this.def.GetModExtension<MechClusterProps>();
            List<Thing> listTurret = new List<Thing>();
            if (props != null)
            {
                foreach (Thing item in GenerateBuildings(props.additionalBuildings, points))
                {
                    item.SetFaction(FactionHeavenForged);
                    listTurret.Add(item);
                }
            }

            //drop
            DropPodUtility.DropThingsNear(intVec, map, listSculpture.Cast<Thing>());
            DropPodUtility.DropThingsNear(intVec, map, listTurret.Cast<Thing>());
            GenSpawn.Spawn(SkyfallerMaker.MakeSkyfaller(ThingDefOf.CrashedShipPartIncoming, thing), intVec, map);//高空坠落物
            list.Add(new TargetInfo(intVec, map));
            SendStandardLetter(parms, list);
            return true;
            
        }

        private static IntVec3 FindDropPodLocation(Map map, Predicate<IntVec3> validator)
        {
            for (int i = 0; i < 200; i++)
            {
                IntVec3 intVec = RCellFinder.FindSiegePositionFrom(DropCellFinder.FindRaidDropCenterDistant(map, allowRoofed: true), map, allowRoofed: true);
                if (validator(intVec))
                {
                    return intVec;
                }
            }
            return IntVec3.Invalid;
        }

        private static IEnumerable<Thing> GenerateBuildings(List<ThingDef> buildings, float point)
        {
            int count = (int)point / 500 + 1;
            int length = buildings.Count;
            for(int i = 0; i < count; i++)
            {
                ThingDef def = buildings[Rand.Range(0, length - 1)];
                Thing thing = ThingMaker.MakeThing(def);
                yield return thing;
            }
            yield break;
        }

    }
}
